package com.cloud.note.service.impl;

import com.cloud.note.dto.sync.SyncLogResponse;
import com.cloud.note.dto.sync.SyncOperationResponse;
import com.cloud.note.dto.sync.SyncStatusResponse;
import com.cloud.note.model.Note;
import com.cloud.note.model.SyncLog;
import com.cloud.note.model.User;
import com.cloud.note.model.constant.SyncStatus;
import com.cloud.note.repository.NoteRepository;
import com.cloud.note.repository.SyncLogRepository;
import com.cloud.note.repository.UserRepository;
import com.cloud.note.service.SyncService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
public class SyncServiceImpl implements SyncService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private NoteRepository noteRepository;

    @Autowired
    private SyncLogRepository syncLogRepository;

    private static boolean isSyncInProgress = false;

    @Override
    public SyncStatusResponse getSyncStatus(String userId) {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));

        // 获取未同步的笔记数量
        List<Note> unsyncedNotes = noteRepository.findByUserIdAndIsTrashedFalse(userId, Pageable.unpaged())
                .getContent()
                .stream()
                .filter(note -> !note.isSynced())
                .collect(Collectors.toList());

        // 获取最后同步时间
        LocalDateTime lastSyncedAt = syncLogRepository.findByUserIdOrderByCreatedAtDesc(userId, Pageable.ofSize(1))
                .stream()
                .findFirst()
                .map(SyncLog::getCreatedAt)
                .orElse(null);

        return SyncStatusResponse.builder()
                .lastSyncedAt(lastSyncedAt)
                .pendingChanges(unsyncedNotes.size())
                .storageUsed(user.getStorageUsed())
                .storageLimit(user.getStorageLimit())
                .isSyncing(isSyncInProgress)
                .build();
    }

    @Override
    @Transactional
    public SyncOperationResponse triggerSync(String userId) {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));

        // 创建同步操作ID
        String syncId = UUID.randomUUID().toString();

        // 如果已经有同步进行中，返回适当的响应
        if (isSyncInProgress) {
            throw new RuntimeException("同步已在进行中，请稍后再试");
        }

        // 异步执行同步操作（在实际应用中，这里应该使用异步任务执行）
        // 这里简化为立即执行同步
        new Thread(() -> {
            try {
                isSyncInProgress = true;

                List<Note> unsyncedNotes = noteRepository.findByUserIdAndIsTrashedFalse(userId, Pageable.unpaged())
                        .getContent()
                        .stream()
                        .filter(note -> !note.isSynced())
                        .collect(Collectors.toList());

                // 模拟同步处理
                for (Note note : unsyncedNotes) {
                    // 创建同步日志
                    SyncLog syncLog = new SyncLog();
                    syncLog.setId(UUID.randomUUID().toString());
                    syncLog.setUserId(userId);
                    syncLog.setType("UPLOAD");
                    syncLog.setEntityType("NOTE");
                    syncLog.setEntityId(note.getId());
                    syncLog.setStatus(SyncStatus.SUCCESS.name());
                    syncLog.setCreatedAt(LocalDateTime.now());

                    syncLogRepository.save(syncLog);

                    // 更新笔记同步状态
                    note.setSynced(true);
                    note.setLastSyncedAt(LocalDateTime.now());
                    noteRepository.save(note);

                    // 模拟延迟
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            } finally {
                isSyncInProgress = false;
            }
        }).start();

        return SyncOperationResponse.builder()
                .syncId(syncId)
                .status(SyncStatus.STARTED.name())
                .startedAt(LocalDateTime.now())
                .build();
    }

    @Override
    public Page<SyncLogResponse> getSyncLogs(String userId, Pageable pageable) {
        Page<SyncLog> syncLogs = syncLogRepository.findByUserIdOrderByCreatedAtDesc(userId, pageable);

        return syncLogs.map(syncLog -> SyncLogResponse.builder()
                .id(syncLog.getId())
                .type(syncLog.getType())
                .entityType(syncLog.getEntityType())
                .entityId(syncLog.getEntityId())
                .status(syncLog.getStatus())
                .errorMessage(syncLog.getErrorMessage())
                .createdAt(syncLog.getCreatedAt())
                .build());
    }
}